﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace AnChao.WPF.Controls.CheckBoxList.Helpers
{
    public class StyleHelper : DependencyObject
    {
        public static Dictionary<ResourceDictionary, ResourceDictionary> AllMergeResourceDictionaries = new Dictionary<ResourceDictionary, ResourceDictionary>();

        public static ResourceDictionary LatestRefResourceDictionary = null;

        #region StyleKey Style关键字

        public static readonly DependencyProperty StyleKeyProperty = DependencyProperty.RegisterAttached("StyleKey", typeof(string), typeof(StyleHelper),
            new FrameworkPropertyMetadata("", (d, e) =>
            {
                FrameworkElement fe = d as FrameworkElement;
                if (fe == null)
                    return;

                Style s = fe.TryFindResource(e.NewValue) as Style;
                fe.Style = s;
            }));

        public static string GetStyleKey(DependencyObject d)
        {
            return (string)d.GetValue(StyleKeyProperty);
        }

        public static void SetStyleKey(DependencyObject d, string value)
        {
            d.SetValue(StyleKeyProperty, value);
        }

        #endregion

        #region MergeResourceDictionary

        public static void SetMergeResourceDictionary(ResourceDictionary obj, Uri value)
        {
            ResourceDictionary mergeResourceDictionary = new ResourceDictionary() { Source = value };

            if (LatestRefResourceDictionary != null)
            {
                AllMergeResourceDictionaries[mergeResourceDictionary] = LatestRefResourceDictionary;

                foreach (object key in mergeResourceDictionary.Keys)
                {
                    Style style = mergeResourceDictionary[key] as Style;
                }
            }

            LatestRefResourceDictionary = mergeResourceDictionary;
            
            obj.MergedDictionaries.Add(mergeResourceDictionary);
        }

        public static void SetInherit(Style style, Type t)
        {
            Style InheritedStyle = null;

            try
            {
                //当前ResourceDictionary需要合并的ResourceDictionary
                ResourceDictionary mergerdDictionary = LatestRefResourceDictionary;

                while (mergerdDictionary != null && InheritedStyle == null)
                {
                    if (mergerdDictionary.Contains(t))
                    {
                        InheritedStyle = mergerdDictionary[t] as Style;
                    }

                    //检查上一级合并的ResourceDictionary
                    else if (AllMergeResourceDictionaries.ContainsKey(mergerdDictionary))
                    {
                        mergerdDictionary = AllMergeResourceDictionaries[mergerdDictionary];
                    }

                    else
                    {
                        mergerdDictionary = null;
                    }
                }
            }
            catch (Exception err)
            {
				throw err;
            }

            if (InheritedStyle != null && InheritedStyle != style)
            {
                InheritStyles(InheritedStyle, style);
            }
        }

		public static void SetStaticBaseOnStyleKey(Style style, object baseStyleKey)
		{
			if (baseStyleKey == null) return;

			Style baseStyle = Application.Current.TryFindResource(baseStyleKey) as Style;

			if (baseStyle != null)
			{
				if (baseStyle != null && baseStyle != style)
				{
					InheritStyles(baseStyle as Style, style);
				}
			}
		}

        private static void InheritStyles(Style src, Style dest)
        {
            if (src.BasedOn != null)
            {
                InheritStyles(src.BasedOn, dest);
            }

            dest.Resources = dest.Resources;
            src.Setters.ToList().ForEach(a => dest.Setters.Add(a));
            src.Triggers.ToList().ForEach(a => dest.Triggers.Add(a));
        }

        #endregion
    }
}
